﻿using AppSocketModel;
using AppSocketModel.Alarm;
using AppSocketService.Account;
using AppSocketService.Vehicle;
using BCGPSCommon;
using BCGPSMongoData;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Text;

namespace AppSocketService.Alarm
{
    public class AlarmPersonService : ServiceBase, IAlarmPersonService
    {
        #region var
        private readonly MongoDBCommand<AlarmDto> mongoDBCommand = new MongoDBCommand<AlarmDto>("Alarm");
        private readonly IRedisService redisService;
        private readonly AccountDto CurrentAccount;
        private readonly IVehiclePersonService vehiclePersonService;
        #endregion
        public AlarmPersonService(IClaimsAccessor claimsAccesso, IRedisService redisService, IAccountPersonService accountPersonService, IVehiclePersonService vehiclePersonService) : base(claimsAccesso)
        {
            this.redisService = redisService;
            this.vehiclePersonService = vehiclePersonService;
            CurrentAccount = accountPersonService.GetCurrentAccount();
            if (CurrentAccount == null)
                throw new Exception("登录账户异常,请重新登录 !!!");
        }
        public AlarmPersonService()
        {

        }

        #region 初始化REDIS用,获取全部报警配置
        public List<AlarmDto> InitRedisGetAll()
        {
            return mongoDBCommand.SelectDocumentsAsync(s => s.CompanyId==0).GetAwaiter().GetResult();
        }
        #endregion


        #region 获取报警配置
        public AlarmDto GetAlarmConfig(string imei)
        {
            if (string.IsNullOrWhiteSpace(imei))
                throw new ArgumentException("设备IMEI号必须填写!");

            if (CurrentAccount.CompanyId > 0)
            {
                return mongoDBCommand.SelectDocumentAsync(s => s.CompanyId == CurrentAccount.CompanyId && s.IMEI == imei).GetAwaiter().GetResult();
            }
            else
            {
                return mongoDBCommand.SelectDocumentAsync(s => s.AccountId == CurrentAccount.AccountId && s.IMEI == imei).GetAwaiter().GetResult();
            }

        }
        #endregion

        #region 获取已经配置的报警类型
        public List<AlarmType> GetAlarmTypes(string imei)
        {

            AlarmDto alarm = GetAlarmConfig(imei);

            List<AlarmType> list = new List<AlarmType>();
            if (alarm == null)
                return list;
            else
            {

                if (alarm.IsAlarm)
                {
                    if (alarm.LightAlarm.IsAlarm)
                        list.Add(AlarmType.Light);
                    if (alarm.LowPowerAlarm.IsAlarm)
                        list.Add(AlarmType.LowPower);
                    if (alarm.FenceAlarm.IsAlarm)
                        list.Add(AlarmType.Fence);
                    if (alarm.MoveAlarm.IsAlarm)
                        list.Add(AlarmType.Move);
                    if (alarm.OverSpeedAlarm.IsAlarm)
                        list.Add(AlarmType.OverSpeed);
                    return list;

                }
                return list;
            }
        }
        #endregion

        #region 获取指定类型的报警配置
        public AlarmTypeBase GetAlarmConfigByType(string imei, AlarmType alarmType)
        {
            AlarmDto alarm = GetAlarmConfig(imei);

            if (alarm == null)
            {
                return null;
            }
            else
            {
                switch (alarmType)
                {
                    case AlarmType.OverSpeed:
                        return alarm.OverSpeedAlarm;
                    case AlarmType.Move:
                        return alarm.MoveAlarm;
                    case AlarmType.Fence:
                        return alarm.FenceAlarm;
                    case AlarmType.LowPower:
                        return alarm.LowPowerAlarm;
                    case AlarmType.Light:
                        return alarm.LightAlarm;
                    default:
                        return null;
                }
            }
        }
        #endregion

        #region 设置指定类型的报警配置
        public bool SetAlarmConfigByType(string imei, AlarmTypeBase alarmSub, AlarmType alarmType)
        {
            AlarmDto alarm = GetAlarmConfig(imei);

            if (alarm == null)
            {
                alarm = new AlarmDto();

                if (CurrentAccount.CompanyId > 0)
                    alarm.CompanyId = CurrentAccount.CompanyId;
                else
                    alarm.AccountId = CurrentAccount.AccountId;

                alarm.IMEI = imei;
                alarm.IsAlarm = false;
            }

            switch (alarmType)
            {
                case AlarmType.OverSpeed:
                    alarm.OverSpeedAlarm = (OverSpeedAlarmDto)alarmSub;
                    break;
                case AlarmType.Move:
                    alarm.MoveAlarm = (MoveAlarmDto)alarmSub;
                    break;
                case AlarmType.Fence:
                    alarm.FenceAlarm = (FenceAlarmDto)alarmSub;
                    break;
                case AlarmType.LowPower:
                    alarm.LowPowerAlarm = (LowPowerAlarmDto)alarmSub;
                    break;
                case AlarmType.Light:
                    alarm.LightAlarm = (LightAlarmDto)alarmSub;
                    break;
                default:
                    break;
            }

            return SetAlarmConfig(alarm);
        }
        #endregion
        
        #region 设备基础报警配置 (根据IMEI)
        public bool SetAlarmBaseConfig(string imei, AlarmBaseDto alarmBaseDto)
        {
            AlarmDto alarm = GetAlarmConfig(imei);

            if (alarm != null)
            {
                alarm.IsAlarm = alarmBaseDto.IsAlarm;
                alarm.AlarmTimeSpan = alarmBaseDto.AlarmTimeSpan;
                alarm.AlarmDateTime = alarmBaseDto.AlarmDateTime;
            }
            else
            {
                alarm = new AlarmDto();


                alarm.IMEI = imei;
                alarm.IsAlarm = alarmBaseDto.IsAlarm;
                alarm.AlarmTimeSpan = alarmBaseDto.AlarmTimeSpan;
                alarm.AlarmDateTime = alarmBaseDto.AlarmDateTime;
            }
            return SetAlarmConfig(alarm);
        }
        #endregion

        #region 设备报警配置 (根据IMEI)
        public bool SetAlarmConfig(AlarmDto dto)
        {
            AlarmDto alarm = GetAlarmConfig(dto.IMEI);

            if (alarm == null)
            {
                if (CurrentAccount.CompanyId > 0)
                {
                    dto.CompanyId = CurrentAccount.CompanyId;

                    VehicleDto vehicle = vehiclePersonService.GetVehicleByImei(dto.IMEI) ?? throw new ArgumentException("IMEI不存在");
                    dto.AccountId = vehicle.AccountId;
                }
                else
                {
                    dto.CompanyId = 0;
                    dto.AccountId = CurrentAccount.AccountId;
                }
                mongoDBCommand.InsertDocumentAsync(dto).GetAwaiter().GetResult();
            }
            else
            {
                dto.ModifyTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
                var update = Builders<AlarmDto>.Update
                    .Set(s => s.IsAlarm, dto.IsAlarm)
                    .Set(s => s.FenceAlarm, dto.FenceAlarm)
                    .Set(s => s.MoveAlarm, dto.MoveAlarm)
                    .Set(s => s.OverSpeedAlarm, dto.OverSpeedAlarm)
                    .Set(s => s.LowPowerAlarm, dto.LowPowerAlarm)
                    .Set(s => s.LightAlarm, dto.LightAlarm)
                    .Set(s => s.AlarmDateTime, dto.AlarmDateTime)
                    .Set(s => s.AlarmTimeSpan, dto.AlarmTimeSpan)
                    .Set(s => s.ModifyTime, BCGPSCommon.MongoDBDateTime.GetNowUtc());
                AlarmDto ret;
                if (CurrentAccount.CompanyId > 0)
                    ret = mongoDBCommand.UpdateDocumentAsync(s => s.CompanyId == CurrentAccount.CompanyId && s.IMEI == dto.IMEI, update).GetAwaiter().GetResult();
                else
                    ret = mongoDBCommand.UpdateDocumentAsync(s => s.AccountId == CurrentAccount.AccountId && s.IMEI == dto.IMEI, update).GetAwaiter().GetResult();

                if (ret == null)
                    throw new ArgumentException("修改失败,请重试!");
            }

            if (dto.IsAlarm)
            {
                redisService.AddAsync(GeneralContainer.RedisNameSpaceIMEIAlarm + dto.IMEI, dto).GetAwaiter().GetResult();
            }
            else
            {
                redisService.AddAsync(GeneralContainer.RedisNameSpaceIMEIAlarm + dto.IMEI, string.Empty).GetAwaiter().GetResult();
            }
            return true;
        }
        #endregion

        #region   根据IMEI删除报警配置   VehiclePersonService.Delete 里面已经删除了Redis 这里就不需要管了
        public void Delete(string Imei)
        {
            AlarmDto alarm = GetAlarmConfig(Imei); 
            if (alarm != null)
            {
                mongoDBCommand.DeleteDocumentAsync(s => s.Id == alarm.Id).GetAwaiter().GetResult(); 
            } 
        }
        #endregion

        #region   删除账户下的全部报警配置
        public void DeleteAll()
        {
            if (CurrentAccount.CompanyId > 0)
                throw new Exception("企业下的个人账户没有删除全部设备报警设置的权限!");


            var list = vehiclePersonService.GetVehicleList();
            foreach (var item in list)
            {
                Delete(item.IMEI);
            }
        }
        #endregion
         
    }
}
